package com.li.onjava8.concurrent.cf;

import java.util.concurrent.CompletableFuture;
import static com.li.onjava8.concurrent.cf.task.CompletableUtilities.*;
/**
 * 这是一个显示所有“基本”操作的示例
 * @author li
 * @date 2023/10/31 9:45
 */
public class CompletableOperations {
    static CompletableFuture<Integer> cfi(int i) {
        return CompletableFuture.completedFuture(Integer.valueOf(i));
    }
    public static void main(String[] args) {
        showr(cfi(1));
        //runAsync: 返回一个新的 CompletableFuture，它由 ForkJoinPool.commonPool() 中运行的任务在运行给定操作后异步完成。。
        voidr(cfi(2).runAsync(() -> System.out.println("runAsync")));
        //thenRunAsync: 返回一个新的 CompletionStage，当此阶段正常完成时，使用此阶段的默认异步执行工具执行给定的操作。
        voidr(cfi(3).thenRunAsync(() -> System.out.println("thenRunAsync")));
        voidr(CompletableFuture.runAsync(() -> System.out.println("runAsync is static")));
        //supplyAsync: 返回一个新的 CompletableFuture，它由 ForkJoinPool.commonPool() 中运行的任务异步完成，其值是通过调用给定的Supplier获得的。
        showr(CompletableFuture.supplyAsync(() -> 99));
        //thenAcceptAsync: 返回一个新的CompletionStage，当此阶段正常完成时，使用此阶段的默认异步执行工具执行该阶段，并将此阶段的结果作为所提供操作的参数。
        voidr(cfi(4).thenAcceptAsync(i -> System.out.println("thenAcceptAsync: " + i)));
        //thenApplyAsync: 返回一个新的CompletionStage，当此阶段正常完成时，将使用此阶段的结果作为所提供函数的参数执行该阶段。
        showr(cfi(5).thenApplyAsync(i -> i + 42));
        //thenComposeAsync: 返回一个新的 CompletionStage，它的完成值与给定函数返回的 CompletionStage 相同，并使用此阶段的默认异步执行工具执行。
        showr(cfi(6).thenComposeAsync(i -> cfi(i + 99)));
        CompletableFuture<Integer> c = cfi(7);
        //强制设置或重置方法 get() 和相关方法随后返回的值，无论是否已完成。 此方法设计为仅在错误恢复操作中使用，即使在这种情况下也可能导致使用已建立的结果与覆盖的结果进行持续的依赖完成。
        c.obtrudeValue(111);
        showr(c);
        //返回此 CompletableFuture。
        showr(cfi(8).toCompletableFuture());
        c = new CompletableFuture<>();
        c.complete(9);
        showr(c);
        c = new CompletableFuture<>();
        //cancel: 如果尚未完成，则使用 CancellationException 完成此 CompletableFuture。 尚未完成的依赖 CompletableFuture 也将异常完成，并由此 CancellationException 引发 CompletionException。
        c.cancel(true);
        System.out.println("cancelled: " + c.isCancelled());
        System.out.println("completed exceptionally:" + c.isCompletedExceptionally());
        System.out.println("done: " + c.isDone());
        System.out.println(c);
        c = new CompletableFuture<>();
        System.out.println(c.getNow(777));
        c = new CompletableFuture<>();
        c.thenApplyAsync(i -> i + 42).thenApplyAsync(i -> i * 12);
        //getNumberOfDependents: 返回其完成正在等待此 CompletableFuture 完成的 CompletableFuture 的估计数量。 该方法设计用于监视系统状态，而不是用于同步控制。
        System.out.println("dependents: " + c.getNumberOfDependents());
        c.thenApplyAsync(i -> i / 2);
        System.out.println("dependents: " + c.getNumberOfDependents());
    }
}

/**
 * CompletionStage是Java8新增的一个接口，用于异步执行中的阶段处理，其大量用在Lambda表达式计算过程中，
 * 目前只有CompletableFuture一个实现类。
 *
 * 一、产出型或者函数型：就是用上一个阶段的结果作为指定函数的参数执行函数产生新的结果。这一类接口方法名中基本都有apply字样，接口的参数是(Bi)Function类型。
 *
 * 二、消耗型或者消费型：就是用上一个阶段的结果作为指定操作的参数执行指定的操作，但不对阶段结果产生影响。这一类接口方法名中基本都有accept字样，接口的参数是(Bi)Consumer类型。
 *
 * 三、不消费也不产出型：就是不依据上一个阶段的执行结果，只要上一个阶段完成（但一般要求正常完成），就执行指定的操作，且不对阶段的结果产生影响。这一类接口方法名中基本都有run字样，接口的参数是Runnable类型。
 *
 * 还有一组特别的方法带有compose字样，它以依赖阶段本身作为参数而不是阶段产生的结果进行产出型（或函数型）操作。
 */